package com.hmdp.utils;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;


// 全局 唯一 Id 是由 时间戳 和 redis 里面的 一个 字段 一起 完成的。

@Component
public class RedisIdWorker {



    @Resource
    private StringRedisTemplate stringRedisTemplate;  // 这个 属性 使用了 自动 赋值 那么 要求 这个 属性 所属的类 要 纳入容器 管理 不然 容器 无法 完成自动 注入 因为 看不到

    private static final int COUNT_BITS = 32;   // 后 32 bit  // 这个 是 左移 的位数 使用 位运算 符  完成 id 的 拼接
    private static final long BEGIN_TIMESTAMP = 1640995200L;  // 初始的

    public Long nextId(String keyPrefix){

        // 首先 获取 时间戳（相对于 开始 的秒数）
        LocalDateTime now = LocalDateTime.now();  //
        // 获取 其 对应二点 实践出

        long l = now.toEpochSecond(ZoneOffset.UTC); // 这个 是 秒数 相对于 开始的 秒数

        long l1 = l - BEGIN_TIMESTAMP;

        // 2.生成序列号
        // 2.1.获取当前日期，精确到天
        String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd")); // 这个是为了保证 每一天的 重新 从1 开始 防止 用完了。  incr的 特性 如果 没有 某个key 会 自动 加上这个 key 然后 赋值0 然后 完成 自增 并返回
        // 2.2.自增长， 加上 date 是为了 防止 redis 单个值的 自增长 到达了 上限 2的 64 次方  并且 我们的 id 里面 这个 只占 32位  所以 同一个 业务 页不能 永远使用 同同一批。
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);  // String 的 命令 可以 让 对应的 key 的值  自增 1 (如果 可以 自增的 话)



        return l1 << COUNT_BITS | count;   // 从前往后 然后就


        // 获取 id 号  在 redis 里面 使用 string incr 来 获取 redsi 是 单县城成

        // 拼接两部分 完成 id
    }

}
